package isquirrel.network;

import isquirrel.beans.Property;
import isquirrel.beans.User;
import isquirrel.util.HibernateUtil;

import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

public class ProfileComparator {
	
	public static double compareUserProfiles(User u1, User u2) {
		
		//Get the sorted list of properties
		List<Property> propertyList1 = getUserSortedProperties(u1); 
		List<Property> propertyList2 = getUserSortedProperties(u2);
		
		//in case any of them is zero
		if (propertyList1.size() == 0 || propertyList2.size() == 0)
			return 0;
		
		//print them out for debugging purposes
		//for (Property p : propertyList1) System.out.println(p.getAttribute()+" "+p.getValue());
		//for (Property p : propertyList2) System.out.println(p.getAttribute()+" "+p.getValue());
		
		Iterator<Property> itr1 = propertyList1.iterator();
		Iterator<Property> itr2 = propertyList2.iterator();

		double sum = 0.0;
		
		Property p1 = itr1.next();
		Property p2 = itr2.next();
		
		//Iterate over the lists until one of them runs out of elements 
		
		while (true) {
			try {
			
				if (p1.compareTo(p2) == 0) {
					
					sum += difference2(p1.getFrequency(),p2.getFrequency());
					p1 = itr1.next();
					p2 = itr2.next();
					
				} else if (p1.compareTo(p2) < 0) {
					p1 = itr1.next();
				} else {
					p2 = itr2.next();
				}
			
			} catch (NoSuchElementException e) {
				break;
			}
		}
		
		return 2 * sum / (sumOfFreqs(propertyList1) + sumOfFreqs(propertyList2));
	}
	
	@SuppressWarnings("unchecked")
	public static List<Property> getUserSortedProperties(User u) {
		return HibernateUtil.getSession().createQuery("from Property where user_id = ? order by attribute, value").setLong(0, u.getUserID()).list();
	}
	
	public static double difference(long freq1, long freq2) {
		return Math.min(freq1, freq2) + (Math.abs(freq1-freq2)/Math.max(freq1, freq2));
	}
	
	public static double difference2(long freq1, long freq2) {
		return Math.min(freq1, freq2) + (Math.abs(freq1-freq2)/2);
	}
	
	public static long sumOfFreqs(List<Property> propertyList) {
		long sum = 0;
		for (Property p : propertyList) {
			sum += p.getFrequency();
		}
		return sum;
	}

}
